using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;

namespace DocumentCreationSystem.Services
{
    /// <summary>
    /// RWKV 清单项（与 manifest.json 的 models 字段对应的最小子集）
    /// </summary>
    public class RWKVModelItem
    {
        public string name { get; set; } = string.Empty;
        public long size { get; set; }
        public string SHA256 { get; set; } = string.Empty;
        public string downloadUrl { get; set; } = string.Empty;
        public List<string>? tags { get; set; }
        public string? category { get; set; } // 可选，manifest 若包含则解析
    }

    /// <summary>
    /// RWKV manifest 根对象
    /// </summary>
    public class RWKVManifest
    {
        public List<RWKVModelItem> models { get; set; } = new();
    }

    /// <summary>
    /// RWKV 模型清单拉取与解析服务
    /// </summary>
    public class RWKVManifestService
    {
        private readonly ILogger<RWKVManifestService> _logger;
        private readonly HttpClient _httpClient;

        public RWKVManifestService(ILogger<RWKVManifestService> logger, HttpClient httpClient)
        {
            _logger = logger;
            _httpClient = httpClient;
            _httpClient.Timeout = TimeSpan.FromSeconds(60);
        }

        /// <summary>
        /// 从分号分隔的多个 URL 拉取清单并合并（去重：按 name）
        /// </summary>
        public async Task<List<RWKVModelItem>> FetchModelsAsync(string urlList, CancellationToken ct = default)
        {
            var result = new Dictionary<string, RWKVModelItem>(StringComparer.OrdinalIgnoreCase);
            var urls = SplitUrlList(urlList);
            foreach (var url in urls)
            {
                try
                {
                    var json = await _httpClient.GetStringAsync(url, ct);
                    if (string.IsNullOrWhiteSpace(json)) continue;

                    using var doc = JsonDocument.Parse(json);
                    if (doc.RootElement.TryGetProperty("models", out var modelsEl) && modelsEl.ValueKind == JsonValueKind.Array)
                    {
                        foreach (var m in modelsEl.EnumerateArray())
                        {
                            var item = new RWKVModelItem
                            {
                                name = m.TryGetProperty("name", out var n) ? (n.GetString() ?? string.Empty) : string.Empty,
                                size = m.TryGetProperty("size", out var s) ? s.GetInt64() : 0,
                                SHA256 = m.TryGetProperty("SHA256", out var h) ? (h.GetString() ?? string.Empty) : string.Empty,
                                downloadUrl = m.TryGetProperty("downloadUrl", out var d) ? (d.GetString() ?? string.Empty) : string.Empty,
                                tags = m.TryGetProperty("tags", out var t) && t.ValueKind == JsonValueKind.Array
                                    ? t.EnumerateArray().Select(x => x.GetString() ?? string.Empty).Where(x => !string.IsNullOrEmpty(x)).ToList()
                                    : null,
                                category = m.TryGetProperty("category", out var c) ? (c.GetString() ?? string.Empty) : null
                            };
                            if (!string.IsNullOrEmpty(item.name))
                            {
                                result[item.name] = item; // 覆盖同名，保留最新
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogWarning(ex, "拉取 RWKV 清单失败: {Url}", url);
                }
            }
            return result.Values.OrderBy(x => x.size).ThenBy(x => x.name).ToList();
        }

        /// <summary>
        /// 分号分隔的 URL 字符串解析
        /// </summary>
        private static List<string> SplitUrlList(string urlList)
        {
            return (urlList ?? string.Empty)
                .Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
                .Select(s => s.Trim())
                .Where(s => !string.IsNullOrEmpty(s))
                .Distinct(StringComparer.OrdinalIgnoreCase)
                .ToList();
        }
    }
}

